home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HPAVC
/
HPAVC CD-ROM.iso
/
PCACHSRC.ZIP
/
WINHULLO.ASM
< prev
next >
Wrap
Assembly Source File
|
1991-08-20
|
13KB
|
394 lines
;WINHULLO.ASM --> WINHULLO.EXE Windows demo program.
;****NOTE**** these WINHULLO files may not be exactly the same as
;those listed in the textbook. The book listings were developed for
;Microsoft C version 6.00 and the SDK. The files have since been
;modified to work with Borland C++ version 2.0. Look at the code
;below and you will see where I have commented-out some code and
;replaced it with more efficient code that TASM can understand.
;You can convert back if necessary.
.MODEL SMALL ;, WINDOWS PASCAL
;the following equates could have been placed in a separate
;include file.... (note that I got these from WINDOWS.H which is
;part of the Microsoft SDK)
IDI_APPLICATION EQU 32512 ;identifier for icon type.
IDC_ARROW EQU 32512 ;identifier for cursor type.
OEM_FIXED_FONT EQU 10 ;identifier for font type.
COLOR_BACKGROUND EQU 1 ;identifier for background colour.
WM_CREATE EQU 1 ;these are messages from Windows.
WM_DESTROY EQU 2 ; /
WM_PAINT EQU 15 ; /
WM_COMMAND EQU 273 ; /
WM_LBUTTONDOWN EQU 513 ; /
WM_CHAR EQU 258 ; /
IDM_QUIT EQU 100 ;menu-identifiers from Windows -- must
IDM_ABOUT EQU 101 ;be same as defined in .RC file.
MB_OK EQU 0 ;a messagebox type.
;......
EXTRN __acrtused:ABS
EXTRN UPDATEWINDOW:FAR ;these are Windows functions.
EXTRN BEGINPAINT:FAR
EXTRN ENDPAINT:FAR
EXTRN DEFWINDOWPROC:FAR
EXTRN POSTQUITMESSAGE:FAR
EXTRN REGISTERCLASS:FAR
EXTRN GETSTOCKOBJECT:FAR
EXTRN CREATEWINDOW:FAR
EXTRN SHOWWINDOW:FAR
EXTRN GETMESSAGE:FAR
EXTRN LOADCURSOR:FAR
EXTRN TRANSLATEMESSAGE:FAR
EXTRN DISPATCHMESSAGE:FAR
EXTRN LOADICON:FAR
EXTRN TEXTOUT:FAR
EXTRN INVALIDATERECT:FAR
EXTRN MESSAGEBOX:FAR
EXTRN GETDC:FAR
EXTRN RELEASEDC:FAR
EXTRN SELECTOBJECT:FAR
.DATA
wintitle DB 'HULLO DEMO PROGRAM',0
winhulloname DB 'WINHULLO',0
hOemFont DW 0 ;handle to OEM font.
_hInst DW 0
outstring DB 'Hullo World'
aboutstr DB 'Assembly Language Windows Demo',0 ;messagebox
titlestr DB 'Karda Prints',0 ; /
.CODE
; PUBLIC WinMain
;WinMain PROC WINDOWS PASCAL NEAR nCmdShow:WORD,lpCmdLine:DWORD,hPrevInstance:WORD,hInstance:WORD
;****NOTE**** the above two lines are an enhancement available with TASM,
;providing high-level stack handling at procedure entry and exit... leave the lines
;commented-out, as this feature is not implemented fully in this file.
PUBLIC WINMAIN
WINMAIN PROC NEAR ;entry point from Windows.
; ;stack will contain return-addr (only 2
; ;bytes), nCmdShow (2), lpCmdLine (4),
; ;hPrevInstance (2), hInstance (2 bytes).
; ;(ret-addr is at top of stack).
push bp ;save BP so can use to access params.
mov bp,sp ;BP will now point to top-of-stack.
sub sp,46 ;mov stack to free region.
cmp WORD PTR [bp+10],0 ;hPrevInstance. (=0 if no previous inst).
jne createwin
;we only come this way if this is the first instance of the application.
;The first instance needs to create certain resources, and all following
;instances can use them....
;(for this Workshop, skip ahead to "createwin:")
;The code below is creating a window-class data-structure, as required
;by RegisterClass() further down....
mov WORD PTR [bp-46],3 ;wndclass
mov WORD PTR [bp-44],OFFSET WinHulloProc ;addr of callback
mov WORD PTR [bp-42],SEG WinHulloProc ;function for window.
sub ax,ax
mov WORD PTR [bp-40],ax
mov WORD PTR [bp-38],ax
mov ax,WORD PTR [bp+12] ;hInstance
mov WORD PTR [bp-36],ax
sub ax,ax ;null -- use Windows default icons.
push ax ; /
mov cx,IDI_APPLICATION ;Default application icon.
sub dx,dx ; /
push dx ; /
push cx ; /
call FAR PTR LOADICON
mov WORD PTR [bp-34],ax
sub ax,ax ;null -- use Windows default cursor.
push ax ; /
mov ax,IDC_ARROW ;Standard arrow cursor.
cwd ; /
push dx ; /
push ax ; /
call FAR PTR LOADCURSOR
mov WORD PTR [bp-32],ax
; mov ax,WHITE_BRUSH
; push ax
; call FAR PTR GETSTOCKOBJECT
mov ax,COLOR_BACKGROUND
mov WORD PTR [bp-30],ax
mov ax,OFFSET DGROUP:winhulloname
mov WORD PTR [bp-28],ax
mov WORD PTR [bp-26],ds
mov WORD PTR [bp-24],ax
mov WORD PTR [bp-22],ds
lea ax,WORD PTR [bp-46] ;wndclass
push ss ;this is address of above data
push ax ;structure.
call FAR PTR REGISTERCLASS ;registers this class of window.
or ax,ax ;
je quitwinmain
createwin:
;CreateWindow() requires the following params on the stack --
;long pointer to window class name, lp to window title, type of window,
;x coord, y coord, width, height, parent-handle, menu-handle, instance-
;handle, lp to params to pass-on.
mov ax,OFFSET DGROUP:winhulloname ;see _DATA segment.
push ds ;long-pointer (far address) of
push ax ;class-name.
mov ax,OFFSET DGROUP:wintitle ;see _DATA segment.
push ds ;far address of window-title.
push ax ; /
sub ax,ax ;type of window (32-bit value).
mov dx,207 ; /
push dx ; /
push ax ; /
mov ax,150 ;x-coord (16-bit).
push ax ; /
sub ax,ax ;y-coord (16-bit).
push ax ; /
mov ax,400 ;width (16-bit).
push ax ; /
mov ax,300 ;height (16-bit).
push ax ; /
sub ax,ax
push ax ;0=no parent for this window.
push ax ;0=use the class menu.
mov ax,WORD PTR [bp+12] ;hInstance -- handle for this
mov WORD PTR _hInst,ax ;application's instance.
push ax ;(passed to applic from Windows).
sub ax,ax
push ax ;0=no params to pass-on.
push ax ;(32-bit long-pointer).
call FAR PTR CREATEWINDOW
mov WORD PTR [bp-2],ax ;returns hWnd in AX
;(handle to the window).
;Here we save it temporarily.
push ax ;ShowWindow() requires hWnd and
push WORD PTR [bp+4] ;nCmdShow ;nCmdShow on the stack.
call FAR PTR SHOWWINDOW ;Tells Windows to display window.
push WORD PTR [bp-2] ;hWnd
call FAR PTR UPDATEWINDOW ;tells Windows to redraw now.
jmp SHORT messageloop ;go to the main message-loop.
;This is the main message loop, in which Windows waits for messages
;by calling GetMessage(), then translates keypresses with
;TranslateMessage() then passes them back to Windows with
;DispatchMessage()....
mainloop:
lea ax,WORD PTR [bp-20] ;far-addr of message.
push ss ; /
push ax ; /
call FAR PTR TRANSLATEMESSAGE
lea ax,WORD PTR [bp-20] ;far-addr of message.
push ss ; /
push ax ; /
call FAR PTR DISPATCHMESSAGE
messageloop:
lea ax,WORD PTR [bp-20] ;long-pointer (far addr) of
push ss ;message. (we use the stack
push ax ;region for convenience).
sub ax,ax
push ax ;null
push ax ;null
push ax ;null
call FAR PTR GETMESSAGE
or ax,ax
jne mainloop
;GetMessage() returns FALSE (AX=0) if a "quit" message...
;so here we are quiting....
mov ax,WORD PTR [bp-16] ;return wParam to Windows.
quitwinmain:
mov sp,bp
pop bp
ret 10 ;Causes RET to add 10 to SP prior to
;popping ret-address, effectively dumping
;all params (as for PASCAL convention).
WINMAIN ENDP
;.....................................................................
;What follows is the "callback" function, that Windows calls after the
;message has been given back to it via DispatchMessage().
;This function employs CASE logic to direct execution to specific
;routines to handle each message. In many cases the message
;cannot be handled by the application, so it is sent back to
;Windows (again!) for default handling....
PUBLIC WinHulloProc
WinHulloProc PROC FAR
;The function is entered with far-return-addr (4 bytes), lParam (4),
;wParam (2), message-type (2), and window-handle (2 bytes) on the stack
;(ret-addr on top).
push ds ;This is some standard preliminary
pop ax ;shuffling of the registers.
nop ; /
inc bp ; / (it is called the prolog code)
push bp ; /
mov bp,sp ; /
push ds ; /
mov ds,ax ; /
ASSUME DS: NOTHING ; / (enters function with DS=_DATA)
sub sp,146 ;move the stack to a free region
;(so as not to mess-up the params).
mov ax,WORD PTR [bp+12] ;get message-type.
cmp ax,WM_CREATE ;message received after CreateWindow()
je xcreate ;function is called.
cmp ax,WM_DESTROY ;message received if a window is closed.
je xquitmessage
cmp ax,WM_PAINT ;message received if Windows has (already)
;redrawn any part of the window (due to
;a size-change for example).
je xpaint
cmp ax,WM_COMMAND ;any selection of the menu will produce
jne notwmcommand
jmp xmenu ;this message.
notwmcommand:
cmp ax,WM_LBUTTONDOWN ;one of many mouse messages.
jne notwmlbutton
jmp xbreak
notwmlbutton:
cmp ax,WM_CHAR ;message that a key pressed.
je xchar
;Default handling of messages....
push WORD PTR [bp+14] ;hWnd
push WORD PTR [bp+12] ;Message-type
push WORD PTR [bp+10] ;wParam
push WORD PTR [bp+8] ;hi-half of lParam
push WORD PTR [bp+6] ;low-half of lParam
call FAR PTR DEFWINDOWPROC
jmp xreturn ;Back to Windows, which will in turn
;return to after DispatchMessage().
;.................................
xcreate:
mov ax,OEM_FIXED_FONT
push ax
call FAR PTR GETSTOCKOBJECT
mov hOemFont,ax ;handle to font.
jmp xbreak
xquitmessage:
sub ax,ax
push ax
call FAR PTR POSTQUITMESSAGE
jmp xbreak
xchar:
;If I wanted this program to display "Hullo World" only when any key is
;pressed, TextOut() would have been placed here.
;note below that BeginPaint() returned a "display context", a handle
;required for drawing, but we don't normally use BeginPaint() outside
;of WM_PAINT cases -- instead we use GetDC()....
;here is what the code would look like if placed here (in C)....
; hDC = GetDC(hWnd);
; TextOut(hDC,10,20,"Hullo World",11);
; ReleaseDC(hWnd,hDC);
;If we want the string to be redrawn everytime the window is redrawn,
;it is better to put TextOut() within the WM_PAINT case... this will
;also mean that "Hullo World" will appear when the window is first drawn.
jmp xbreak
xpaint:
push WORD PTR [bp+14] ;hWnd -- handle of current window.
lea ax,WORD PTR [bp-42] ;ps -- far-addr of paint-structure.
push ss ;(BeginPaint() will fill the structure).
push ax ; /
call FAR PTR BEGINPAINT ;BeginPaint() returns handle hDC.
mov WORD PTR [bp-146],ax ;hDC -- display-context, required
;before can output to screen.
;For this simple demo, any redraw of the Window will cause output of our
;"hullo world" string....
;Windows by default uses the System font, but I
;am changing it. I need to attach the new font to the
;display....
; push ax ;hDC
; push hOemFont
; call FAR PTR SELECTOBJECT ;attaches hOemFont to hDC.
call SelectObject PASCAL,ax,hOemFont ;TASM replacement.
push WORD PTR [bp-146] ;hDC ;hDC
mov ax,10 ;16-bit x-coord
push ax ; /
mov ax,20 ;16-bit y-coord
push ax ; /
mov ax,offset outstring ;far-address of string to o/p
push ds ; /
push ax ; / (note low half pushed 2nd)
mov ax,11 ;number of chars in string.
push ax
call FAR PTR TEXTOUT
push WORD PTR [bp+14] ;hWnd
lea ax,WORD PTR [bp-42] ;ps -- far-addr of paint-structure.
push ss ;(filled by BeginPaint()).
push ax ; /
call FAR PTR ENDPAINT
jmp SHORT xbreak
;........................
xmenu:
;comes here if WM_COMMAND message. The two parameters associated with
;the message, lParam & wParam, tell us more....
;low-order word of lParam=0 if message is a menu-selection.
;hi-order word of lParam=1 if message is an accelerator-key.
;If low/lParam<>0, message is from a "control" (such as a scrollbar), and
;low/lParam=handle of control, hi/lParam=notification code.
;wParam contains the menu-item, the control-ID or the accelerator-key-ID.
;let's stick with menus... the .RC file assigns the number for each
;menu-item, and this is what we look for in wParam...
cmp WORD PTR [bp+6],0 ;low-half of lParam
jne xbreak ;test if a menu-message.
cmp WORD PTR [bp+10],IDM_QUIT ;wParam.
jne notquit
jmp xquitmessage
notquit:
cmp WORD PTR [bp+10],IDM_ABOUT
jne xbreak ;no other menu items.
;let's put up a message about this program...
; push WORD PTR [bp+14] ;hWnd -- handle of parent window.
; mov ax,OFFSET aboutstr ;far-addr of string to display.
; push ds ; /
; push ax ; /
; mov ax,OFFSET titlestr ;far-addr of title of dialog-box.
; push ds ; /
; push ax ; /
; mov ax,MB_OK ;type of message-box.
; push ax ; / (displays single "ok" button)
; call FAR PTR MESSAGEBOX
call MessageBox PASCAL,WORD PTR [bp+14],SEG aboutstr,OFFSET aboutstr,SEG titlestr,OFFSET titlestr,MB_OK
;TASM replacement***
;.........................
xbreak:
sub ax,ax ;returns 0 in DX:AX. (callback functions
cwd ;return a 32-bit (long) value).
xreturn:
dec bp ;final standard manipulation of regs.
dec bp ; /
mov sp,bp ; / (it is called the epilog code).
pop ds ; /
pop bp ; /
dec bp ; /
ret 10 ;removes parameters.
WinHulloProc ENDP
;.....................................................................
END